/**
 * \file
 * Neuron DLA Muxer API
 * ---
 * Neuron DLA Muxer provides APIs to create runtime NeuronDLAMuxer for parsing packed DLA files, and do
 * inference with specified DLA in the pool.
 * \n The Runtime user should include this header to use Neuron DLA Muxer API.
 */

#pragma once

#if __has_include("Types.h")
#include "Types.h"
#else
#include "neuron/api/Types.h"
#endif

#include <stddef.h>
#include <stdint.h>
#include <sys/cdefs.h>

__BEGIN_DECLS

/**
 * Create a NeuronDLAMuxer based on the setting specified in options and the packed DLAs file
 * generated by dla-packer. The address of the created instance will be passed back in *dlaMuxer.
 * @param pathToDLB The path to the bundled DLA file.
 * @param options The environment options for the created NeuronDLAMuxer.
 * @param dlaMuxer DLAMuxer provides API for run a compiled network with a bundled DLA (.dlb) file.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_createWithOptions(const char* pathToDLB, const char* options, void** dlaMuxer);

/**
 * Get number of DLAs in the dlaMuxer.
 * @param dlaMuxer The address of the created NeuronDLAMuxer instance.
 * @param dlaCount The total number of DLAs in the dlaMuxer.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_getDLACount(void* dlaMuxer, size_t* dlaCount);

/**
 * Get the index of DLA specified by input name, and return it by dlaIndex.
 * @param dlaMuxer The address of the created NeuronDLAMuxer instance.
 * @param name A null-terminated string which indicates the name of target DLA in the dlaMuxer.
 * @param dlaIndex The pointer to store the returned index for the target DLA.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_getIndexByName(void* dlaMuxer, const char* name, size_t* dlaIndex);

/**
 * Do inference with specified DLA set with selectDLA API.
 * @param dlaMuxer The address of the created NeuronDLAMuxer instance.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_inference(void* dlaMuxer);

/**
 * Set the memory buffer for all the extracted static tensors in the network of the selected DLA.
 * If the binary file to the extracted static data is packed into the .dlb file by dla-packer at
 * bundle time, DLAMuxer will automatically allocate a static data buffer from the bundled binary
 * file, and set all the extracted static tensor from the buffer. If all the parameters (address,
 * size, and file descriptor in attribute) to this API are valid, DLAMuxer prefers to use the
 * provided buffer instead of the DLAMuxer-allocated buffer (if existed).
 * @param dlaMuxer The address of the created neuron NeuronDLAMuxer instance.
 * @param staticDataBuffer The extracted static data buffer.
 * @param length The extracted static data buffer size.
 * @param attribute The buffer attribute for the set buffer.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_setStaticData(void* dlaMuxer, const void* staticDataBuffer, size_t length,
                                 BufferAttribute attribute);

/**
 * Select a specific DLA in the dlaMuxer by a given index. The selected DLA will act as the
 * operation target for later API calls.
 * @param dlaMuxer The address of the created neuron NeuronDLAMuxer instance.
 * @param index The DLA index to select.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_selectDLA(void* dlaMuxer, size_t index);

/**
 * Get the size of DLA name for the selected DLA.
 * @param dlaMuxer The address of the created neuron NeuronDLAMuxer instance.
 * @param size The size of the DLA name.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_getDLANameSize(void* dlaMuxer, size_t* size);

/**
 * Get the file name for the selected DLA.
 * @param dlaMuxer The address of the created neuron NeuronDLAMuxer instance.
 * @param name The destination buffer to store the output DLA name.
 * @param size The size of the destination buffer.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_getDLAName(void* dlaMuxer, char* name, size_t size);

/**
 * Set the memory buffer for the tensor which hold the specified input handle in the original
 * network of the selected DLA. If there are multiple inputs, each of them have to be set.
 * @param dlaMuxer The address of the created neuron NeuronDLAMuxer instance.
 * @param handle The frontend IO index.
 * @param buffer The input buffer.
 * @param length The input buffer size.
 * @param attribute The buffer attribute for setting ION.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_setInput(void* dlaMuxer, uint64_t handle, const void* buffer, size_t length,
                            BufferAttribute attribute);

/**
 * Set the memory buffer and offset for the tensor which hold the specified input handle in the
 * original network for the selected DLA. If there are multiple inputs, each of them have to be set.
 * @param dlaMuxer The address of the created neuron NeuronDLAMuxer instance.
 * @param handle The frontend IO index.
 * @param buffer The input buffer.
 * @param length The input buffer size.
 * @param attribute The buffer attribute for setting ION.
 * @param offset The offset for ION buffer.
 * @param offset Reading ION buffer from start addr + offset.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_setOffsetedInput(void* dlaMuxer, uint64_t handle, const void* buffer,
                                    size_t length, BufferAttribute attribute, size_t offset);

/**
 * Set the memory buffer for the tensor which hold the specified output handle in the original
 * network for the selected DLA. If there are multiple outputs, each of them have to be set.
 * @param dlaMuxer The address of the created neuron NeuronDLAMuxer instance.
 * @param handle The frontend IO index.
 * @param buffer The output buffer.
 * @param length The output buffer size.
 * @param attribute The buffer attribute for setting ION.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_setOutput(void* dlaMuxer, uint64_t handle, void* buffer, size_t length,
                             BufferAttribute attribute);

/**
 * Set the memory buffer and offset for the tensor which hold the specified output handle in the
 * original network for the selected DLA. If there are multiple outputs, each of them have to be
 * set.
 * @param dlaMuxer The address of the created neuron NeuronDLAMuxer instance.
 * @param handle The frontend IO index.
 * @param buffer The output buffer.
 * @param length The output buffer size.
 * @param attribute The buffer attribute for setting ION.
 * @param offset Writing ION buffer from start addr + offset.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_setOffsetedOutput(void* dlaMuxer, uint64_t handle, void* buffer, size_t length,
                                     BufferAttribute attribute, size_t offset);

/**
 * Get metadata info in the selected DLA in the dlaMuxer, which is provided through compiler option
 * --dla-metadata.
 * @param dlaMuxer The address of the created neuron NeuronDLAMuxer instance.
 * @param key The key for the target data
 * @param size The size of the target data. If there is no corresponding metadata, size is 0.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_getMetadataInfo(void* dlaMuxer, const char* key, size_t* size);

/**
 * Get metadata in the selected DLA in the dlaMuxer, which is provided through compiler option
 * --dla-metadata.
 * @param dlaMuxer The address of the created neuron NeuronDLAMuxer instance.
 * @param key The key for the target data
 * @param data The destination data buffer.
 * @param size The size to read from metadata.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_getMetadata(void* dlaMuxer, const char* key, char* data, size_t size);

/**
 * Set the QoS configuration for the selected Neuron Runtime.
 * If qosOption.profiledQoSData is not nullptr, the selected Neuron Runtime would use it as the
 * profiled QoS data.
 * @param dlaMuxer The address of the created NeuronDLAMuxer instance.
 * @param qosOption The option for QoS configuration.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_setQoSOption(void* dlaMuxer, const QoSOptions* qosOption);

/**
 * Get the profiled QoS data and executing boost value (the actual boost value during execution).
 * If *profiledQoSData is nullptr, the selected Neuron Runtime would allocate *profiledQoSData.
 * Otherwise, the selected Neuron Runtime would only update its fields.
 * *profiledQoSData is actually allocated as a smart pointer in the selected Neuron Runtime
 * instance, so the lifetime of *profiledQoSData is the same as the selected Neuron Runtime.
 * Caller should be careful about the usage of *profiledQoSData,
 * and never touch the allocated *profiledQoSData after NeuronDLAMuxer_release.
 * @note This function is not supported on MediaTek TV platforms (MT99XX/MT96XX/MT76XX/MT58XX).
 * @param dlaMuxer The address of the created NeuronDLAMuxer instance.
 * @param profiledQoSData The profiled QoS raw data.
 * @param execBoostValue The executing boost value (the actual boot value set in device) based on
 *                       scheduling policy.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_getProfiledQoSData(void* dlaMuxer, ProfiledQoSData** profiledQoSData,
                                      uint8_t* execBoostValue);

/**
 * Get the physical size required by the buffer of the input tensor (specified by handle).
 * Pass back the expected buffer size (byte) in *size for the tensor which holds the specified
 * input handle.
 * @param dlaMuxer The address of the created NeuronDLAMuxer instance.
 * @param handle The frontend IO index.
 * @param size The input buffer size.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_getInputSize(void* dlaMuxer, uint64_t handle, size_t* size);

/**
 * Get the rank required by the input tensor (specified by handle).
 * Pass back the expected rank in *rank for the tensor which holds the specified input handle.
 * @param dlaMuxer The address of the created NeuronDLAMuxer instance.
 * @param handle The frontend IO index.
 * @param rank The input rank.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_getInputRank(void* dlaMuxer, uint64_t handle, uint32_t* rank);

/**
 * Get the physical size required by the buffer of the input tensor (specified by handle) with
 * hardware alignments. This function passes back the expected buffer size (byte) in *size for the
 * tensor which holds the specified input handle. The value in *size has been aligned to hardware
 * required size, and it can be used as ION buffer size for the specified input when
 * suppressInputConversion is enabled.
 * @param dlaMuxer The address of the created NeuronDLAMuxer instance.
 * @param handle The frontend IO index.
 * @param size The input buffer size.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_getInputPaddedSize(void* dlaMuxer, uint64_t handle, size_t* size);

/**
 * Get the size in pixels for each dimensions of the input tensor (specified by handle).
 * This function passes back the expected size (in pixels) of each dimensions in *dim for the tensor
 * which holds the specified input handle. The sizes of each dimensions in *dim have been aligned
 * to hardware required sizes. When suppressInputConversion is enabled, the values in *dim are the
 * required sizes of each dimensions for the specified input.
 * @param dlaMuxer The address of the created NeuronDLAMuxer instance.
 * @param handle The frontend IO index.
 * @param dims The size (in pixels) of each dimensions.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_getInputPaddedDimensions(void* dlaMuxer, uint64_t handle,
                                            RuntimeAPIDimensions* dims);

/**
 * Get the physical size required by the buffer of the output tensor (specified by handle) for the
 * selected DLA. This function passes back the expected buffer size (byte) in *size for the tensor
 * which holds the specified output handle.
 * @param dlaMuxer The address of the created neuron NeuronDLAMuxer instance.
 * @param handle The frontend IO index.
 * @param size The output buffer size.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_getOutputSize(void* dlaMuxer, uint64_t handle, size_t* size);

/**
 * Get the physical size required by the buffer of the output tensor (specified by handle) with
 * hardware alignments. This function passes back the expected buffer size (byte) in *size for the
 * tensor which holds the specified output handle. The value in *size has been aligned to hardware
 * required size, and it can be used as ION buffer size for the specified output when
 * suppressOutputConversion is enabled.
 * @param dlaMuxer The address of the created NeuronDLAMuxer instance.
 * @param handle The frontend IO index.
 * @param size The output buffer size.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_getOutputPaddedSize(void* dlaMuxer, uint64_t handle, size_t* size);

/**
 * Get the size in pixels for each dimensions of the output tensor (specified by handle).
 * This function passes back the expected size (in pixels) of each dimensions in *dim for the tensor
 * which holds the specified output handle. The sizes of each dimensions in *dim have been aligned
 * to hardware required sizes. When suppressOutputConversion is enabled, the values in *dim are the
 * required sizes of each dimensions for the specified output.
 * @param dlaMuxer The address of the created NeuronDLAMuxer instance.
 * @param handle The frontend IO index.
 * @param dims The size (in pixels) of each dimensions.
 * @return A RuntimeAPI error code.
 */
int NeuronDLAMuxer_getOutputPaddedDimensions(void* dlaMuxer, uint64_t handle,
                                             RuntimeAPIDimensions* dims);

/**
 * Release all the runtime resources in the NeuronDLAMuxer.
 * @param dlaMuxer The address of the created neuron NeuronDLAMuxer instance.
 */
void NeuronDLAMuxer_release(void* dlaMuxer);

__END_DECLS
